package com.se.dao.es;

import cn.hutool.core.util.StrUtil;
import com.se.domain.mysql.ActivityDO;
import com.se.domain.qo.ActESQO;
import com.se.domain.request.param.SearchActParam;
import com.se.util.MyDateUtil;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Repository
public class ActESDao {
    @Autowired
    RestHighLevelClient client;
    String indexName = "activity_es";
    public List<ActESQO> searchAct(SearchActParam param) throws IOException {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //关键词不为空
        if(!StrUtil.isBlank(param.getKey())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("title", param.getKey()));
        }
        //cat分区不是全部
        if(param.getCatId() != 0){
            boolQueryBuilder.must(QueryBuilders.termQuery("cat_ids", param.getCatId()));
        }

        //排序设置
        SortOrder order;
        if(param.getDesc() != null && param.getDesc())
            order = SortOrder.DESC;
        else order = SortOrder.ASC;

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(boolQueryBuilder);
        if(param.getSort() != null) {
            switch (param.getSort()) {
                case "" -> {
                }
                case "start" -> {
                    searchSourceBuilder.sort("start_time", order);
                }
                case "end" -> {
                    searchSourceBuilder.sort("end_time", order);
                }
            }
        }
        //分页设置
        searchSourceBuilder
                .from(param.getPage().getPage())
                .size(param.getPage().getSize());

        // 构建高亮设置
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .field("title")
                .preTags("<font color=\"red\">")
                .postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);


        // 构建搜索请求
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(searchSourceBuilder);

//        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
//                .query(boolQueryBuilder)
//                .sort("start_time")  // 按照 start_time 排序
//                .from(0)
//                .size(20)
//                .highlighter(highlightBuilder);


        // 执行搜索
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        List<ActESQO> res = new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits()) {
            ActESQO esqo = new ActESQO(
                    Long.parseLong(hit.getSourceAsMap().get("act_id").toString()),
                    hit.getSourceAsMap().get("title").toString()
            );
            // 获取高亮显示的文本
            HighlightField titleHighlight = hit.getHighlightFields().get("title");
            if (titleHighlight != null) {
                esqo.setTitle(titleHighlight.fragments()[0].string());
            }

            res.add(esqo);
        }

        return res;
    }

    public void createAct(ActivityDO activityDO) throws IOException {
        IndexRequest indexRequest = new IndexRequest(this.indexName)
                .id(String.valueOf(activityDO.getActId())) // 使用 actId 作为唯一标识符
                .source("act_id", activityDO.getActId(),
                        "title", activityDO.getTitle(),
                        "info", activityDO.getInfo(),
                        "start_time", activityDO.getStartTime(),
                        "end_time", activityDO.getEndTime(),
                        "apply_time", activityDO.getApplyTime(),
                        "apply_end_time", activityDO.getApplyEndTime(),
                        "cat_ids", activityDO.getCatIds().split(",")); // 假设 catIds 是一个整数数组

        // 执行插入操作
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
    }

    public void removeAct(Long actId) throws IOException {
        // 构建删除请求，直接指定文档的 _id 为 catId
        DeleteRequest deleteRequest = new DeleteRequest(this.indexName, String.valueOf(actId));
        // 执行删除操作
        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);

//        // 处理删除结果
//        if (deleteResponse.getResult() == DeleteResponse.Result.DELETED) {
//            System.out.println("Document with _id/catId " + catIdToDelete + " deleted successfully");
//        } else {
//            System.err.println("Failed to delete document with _id/catId " + catIdToDelete);
//        }
    }

    //TODO 暂不执行
//    @Scheduled(cron = "0 0 0 * * ?") // 每天零点执行,删除ES数据库中已经结束的活动
    public void cleanupExpiredActivities() {
        // 获取当前时间
        Date currentDateTime = new Date();

        // 格式化当前时间为 "yyyy-MM-dd HH:mm" 格式
        String dateStr = MyDateUtil.sdf.format(currentDateTime);

        // 构建删除请求
        DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(this.indexName)
                .setQuery(QueryBuilders.rangeQuery("end_time").lt(dateStr)); // 删除 end_time 小于当前时间的项

        try {
            client.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
#### 活动表Activity_ES

| 名称           | 类型        | 说明           |
| -------------- | ----------- | -------------- |
| act_id         | number      | 活动ID         |
| cat_ids        | array       | 分区类型ID数组 |
| title          | text        | 活动标题       |
| info           | text        | 活动内容       |
| start_time     | varchar(32) | 活动开始时间   |
| end_time       | varchar(32) | 活动结束时间   |
| apply_time     | varchar(32) | 报名开始时间   |
| apply_end_time | varchar(32) | 报名结束时间   |
 */